/* 
 * File:   Properties.h
 * Author: ferranferri
 *
 * Created on May 14, 2013, 5:05 PM
 */
#pragma once
#ifndef PROPERTIES_H
#define	PROPERTIES_H

#include "core/core_utils.h"
#include "Log/LogSystem.h"
#include "json/json.h"

namespace Json {
    class Value;
}

namespace z3d {
    namespace utils {

        class Properties {
        private:
            std::string _fileName;
            const bool _readOnly;
            glog::CGlobalLog& _log;
            Json::Value* _docRoot;
            const Properties* _parent;
        protected:
            /**
             *  Check if a property prop exists in member list m
             * @param m
             * @param prop
             * @return true if the property exists
             */
            bool propertyExists(const Json::Value::Members& m, const std::string& prop);
            /**
             * Check if property is a path (prop1/prop2/...)
             * @param property
             * @return true if is a path
             */
            bool isPath(const std::string& property);
            /**
             * Gets a property as Json as object or returns the default value. It admits a path format
             * that dig into the structure like /level1/level2/level3
             * @param propName the name of the property or the path to arrive.
             * @param defaultValue The default value if no property is found.
             * @return 
             */
            const Json::Value getPropertyAsObject(const std::string& propName, const Json::Value* defaultValue, const Json::Value root);
        public:
            /**
             * Check if a property prop exists in the selected level
             * @param prop
             * @return true if the property exists in this level
             */
            bool exists(const std::string& prop);
            Properties(const std::string& fileName, bool readonly);
            Properties(const Properties& p);
            bool processFile();
            
            /**
             * Returns a properties object that contains a sub object from property
             * @param property The propery you are searching for. Path style property aren't admited.
             * @return A Properties object
             */
            Properties* getChild(const std::string& property);

            void setFileName(const std::string fileName) {
                _fileName = fileName;
            }

            const std::string getFileName() const {
                return _fileName;
            }       
            
            std::string getPropertyAsString(const std::string& propName, const std::string& defaultValue);
            uint32_t getPropertyAsUnsigned(const std::string& propName, const uint32_t& defaultValue);
            int32_t getPropertyAsSigned(const std::string& propName, const int32_t& defaultValue);
            float getPropertyAsDouble(const std::string& propName, const float& defaultValue);
            bool getPropertyAsBoolean(const std::string& propName, const bool& defaultValue);
            virtual ~Properties();
            
        private:

        };
    }
}
#endif	/* PROPERTIES_H */

